Function.prototype.luckyCall = function (ctx, ...args) {
    //1.将方法挂载到我们传入的ctx
    //2.将挂载以后的方法调用
    //3.将我们添加的这个属性删除
    if (typeof this !== 'function') {
        throw new TypeError('必须传入函数')
    }
    let fn = Symbol(1)
    ctx[fn] = this
    ctx[fn](...args)
    delete ctx[fn]
}

function show(...args) {
    console.log(args)
    console.log(this.name)
}

Function.prototype.luckyApply = function (ctx, args = []) {
    //1.将方法挂载到我们传入的ctx
    //2.将挂载以后的方法调用
    //3.将我们添加的这个属性删除
    if (typeof this !== 'function') {
        throw new TypeError('必须传入函数')
    }
    if (args && !(args instanceof Array)) {
        throw ('luckyApply 只接受数组作为参数')
    }
    let fn = Symbol(1)
    ctx[fn] = this
    ctx[fn](...args)
    delete ctx[fn]

}

Function.prototype.luckyBind = function (ctx, ...args1) {
    //1.将方法挂载到我们传入的ctx
    //2.将挂载以后的方法调用
    //3.将我们添加的这个属性删除
    const that = this
    return function F(...args2) {
        if (this instanceof F) {
            return new that(...args1, ...args2)
        }
        return that.call(ctx, ...args1, ...args2)
    }
}
show.luckyCall({ name: 'luckCall' }, 'luckyCall 1', 'lucjyCall 2', 'luckyCall 3')

// show.luckyApply({ name: 'luckCall' }, ['luckyCall 1', 'lucjyCall 2', 'luckyCall 3'])

let bind = show.luckyBind({ name: 'luckyBind-11' }, 'luckyCall 1', 'lucjyCall 2', 'luckyCall 3')
bind()
// var b = new bind('luckyCall 4')



